﻿using DBUtil;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using DotNetCommon.Extensions;
using System.Diagnostics;
using System.Threading;

namespace DistributeLockTests
{
    internal class Program
    {
        //sqlserver 2014
        private static DBAccess db = DBFactory.CreateDB("SQLSERVER", "Data Source=192.168.0.19;Initial Catalog=test;User ID=sa;Password=123456;Pooling=True;Max Pool Size=20000;Encrypt=True; TrustServerCertificate=True;");
        static void Main(string[] args)
        {
            //TestNoLock();
            TestWithLock();

            Console.WriteLine("ok");
        }

        public static void TestWithLock()
        {
            //准备数据
            db.Manage.DropTableIfExist("test");
            db.ExecuteSql("create table test(id int primary key,money int)");
            db.Insert("test", new { id = 1, money = 100 }.ToDictionary());

            var key = "keystring";
            var timeoutsecond = 2;

            var tasks = new List<Task>();
            for (int i = 0; i < 10; i++)
            {
                var tmp = i;
                tasks.Add(Task.Run(() =>
                {
                    db.RunInLock(key, () =>
                    {
                        var current = db.SelectScalar<int>("select money from test where id=1");
                        Console.WriteLine($"{DateTime.Now.ToCommonStampString()} 任务: {tmp} 当前:{current}");
                        current += 50;
                        db.Update("test", new { money = current }.ToDictionary(), new { id = 1 }.ToDictionary());
                        current = db.SelectScalar<int>("select money from test where id=1");
                        Console.WriteLine($"{DateTime.Now.ToCommonStampString()} 任务: {tmp} 增加50后:{current}");
                    }, timeoutsecond);
                }));
            }
            Task.WaitAll(tasks.ToArray());
            var money = db.SelectScalar<int>("select money from test where id=1");
            Console.WriteLine($"money={money}");
        }

        public static void TestNoLock()
        {
            //准备数据
            db.Manage.DropTableIfExist("test");
            db.ExecuteSql("create table test(id int primary key,money int)");
            db.Insert("test", new { id = 1, money = 100 }.ToDictionary());

            var tasks = new List<Task>();
            for (int i = 0; i < 10; i++)
            {
                var db2 = db.CreateNewDB();
                var tmp = i;
                tasks.Add(Task.Run(() =>
                {
                    var current = db2.SelectScalar<int>("select money from test where id=1");
                    Console.WriteLine($"{DateTime.Now.ToCommonStampString()} 任务: {tmp} 当前:{current}");
                    current += 50;
                    db2.Update("test", new { money = current }.ToDictionary(), new { id = 1 }.ToDictionary());
                    current = db2.SelectScalar<int>("select money from test where id=1");
                    Console.WriteLine($"{DateTime.Now.ToCommonStampString()} 任务: {tmp} 增加50后:{current}");
                }));
            }
            Task.WaitAll(tasks.ToArray());
            var money = db.SelectScalar<int>("select money from test where id=1");
            Console.WriteLine($"money={money}");
        }
    }
}
